package com.lz.gmall.product.service.Impl;

import com.lz.gmall.constant.GmallConstant;
import com.lz.gmall.product.biz.SkuDetailBizService;
import com.lz.gmall.product.service.BloomFilterService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class BloomFilterServiceImpl implements BloomFilterService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private SkuDetailBizService skuDetailBizService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public void resetBloomFilter() {

        List<Long> skuIdList = skuDetailBizService.getAllStuIdByRpc();

        //重建新的布隆过滤器
        RBloomFilter<Long> bloomFilter = redissonClient.getBloomFilter(GmallConstant.REDIS_REDISSON_BLOOM_FILTER_NEW);
        if (!bloomFilter.isExists()){
            bloomFilter.tryInit(100000,0.000001);
            skuIdList.forEach(skuId->{
                bloomFilter.add(skuId);
            });
        }
        //删除之前的布隆过滤器，采用lua脚本，然后新的布隆过滤器名为之前的名字
        //保证了删除的原子性，并且可以让这个方法具有通用性，如果就叫这个新名字，下次再执行这个方法就会出问题
        String script = "redis.call(\"del\",KEYS[1])\n" +
                "redis.call(\"del\",\"{\"..KEYS[1]..\"}:config\")\n" +
                "redis.call(\"rename\",KEYS[2],KEYS[1])\n" +
                "redis.call(\"rename\",\"{\"..KEYS[2]..\"}:config\",\"{\"..KEYS[2]..\"}:config\")\n" +
                "return 1";

        Long aLong = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class)
                , Arrays.asList(GmallConstant.REDIS_REDISSON_BLOOM_FILTER, GmallConstant.REDIS_REDISSON_BLOOM_FILTER_NEW));
        if (aLong == 1){
            log.info("布隆过滤器重构成功");
        }
    }
}
